package com.yds.bluetooth

import android.Manifest
import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.bluetooth.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.yds.bluetooth.utils.YDSDelayHelper
import com.yds.bluetooth.utils.YDSRepeatClickRefuseHelper
import com.yds.bluetooth.views.TempData
import java.lang.Exception

/**
 * 蓝牙助手
 */
@SuppressLint("StaticFieldLeak")
@Suppress("Unused")
object YDSBluetoothHelper {
    private const val Tag = "YDS蓝牙"

    // 是否是经典蓝牙模式
    private var isClassicType: Boolean = false
    private var mContext: Context? = null
    private var mOnConnectStateChangedListener: OnConnectStateChangedListener? = null
    private var progressDialog: ProgressDialog? = null

    private var bluetoothAdapter: BluetoothAdapter? = null

    /**
     * 初始化经典蓝牙适配器
     * @param context 上下文
     * @return true-设备支持蓝牙 false-设备不支持蓝牙
     */
    fun initClassic(context: FragmentActivity, listener: OnConnectStateChangedListener? = null): Boolean {
        this.mContext = context
        this.mOnConnectStateChangedListener = listener
        isClassicType = true

        val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        bluetoothAdapter = bluetoothManager.adapter
        if (null == bluetoothAdapter || !context.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Log.i(Tag, "当前设备不支持蓝牙功能")
            Toast.makeText(mContext, context.resources.getString(R.string.str_no_support), Toast.LENGTH_SHORT).show()
            return false
        }

        progressDialog = ProgressDialog(context)
        progressDialog?.setMessage(context.resources.getString(R.string.str_search_all_type))
        progressDialog?.setCancelable(false)

        onRegisterBluetoothDeviceConnectStateObserver()

        return true
    }

    /**
     * 初始化低功耗蓝牙适配器
     * @param context 上下文
     * @param serviceUuid 服务uuid
     * @param characterWriteUuid 写入特征值uuid
     * @param characterNotifyUuid 通知特征值uuid
     * @return true-设备支持蓝牙 false-设备不支持蓝牙
     */
    fun initBle(context: AppCompatActivity, serviceUuid: String, characterWriteUuid: String, characterNotifyUuid: String, listener: OnConnectStateChangedListener? = null): Boolean {
        this.mContext = context
        this.mOnConnectStateChangedListener = listener
        isClassicType = false

        val bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        bluetoothAdapter = bluetoothManager.adapter
        if (null == bluetoothAdapter || !context.packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            Log.i(Tag, "当前设备不支持蓝牙功能")
            Toast.makeText(mContext, context.resources.getString(R.string.str_no_support), Toast.LENGTH_SHORT).show()
            return false
        }

        // 初始化uuid
        if (serviceUuid.isNotEmpty() && characterWriteUuid.isNotEmpty() && characterNotifyUuid.isNotEmpty()) {
            ConnectBleDeviceManager.initUuid(serviceUuid, characterWriteUuid, characterNotifyUuid)
        }

        progressDialog = ProgressDialog(context)
        progressDialog?.setMessage(context.resources.getString(R.string.str_search_ble_type))
        progressDialog?.setCancelable(false)

        onRegisterBluetoothDeviceConnectStateObserver()
        return true
    }

    /**
     * 校验权限
     */
    private fun checkPermission(): Boolean {
        mContext?.let {
            if (ContextCompat.checkSelfPermission(it, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(it, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED
                || ContextCompat.checkSelfPermission(it, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
            ) {
                Toast.makeText(mContext, it.resources.getString(R.string.str_lost_permission), Toast.LENGTH_SHORT).show()
                return false
            }
        } ?: kotlin.run {
            return false
        }

        return true
    }

    /**
     * 请求蓝牙权限
     */
    fun requestPermission(context: FragmentActivity, requestCode: Int) {
        ActivityCompat.requestPermissions(
            context, arrayOf(
                Manifest.permission.BLUETOOTH,
                Manifest.permission.BLUETOOTH_ADMIN,
                Manifest.permission.ACCESS_COARSE_LOCATION
            ), requestCode
        )
    }

    // 蓝牙搜索状态
    private var scanBluetoothDeviceState = false

    /**
     * 扫描蓝牙设备
     * @param enable true-开始扫描 false-停止扫描
     * @param showAnim true-展示扫描提示 false-停止扫描提示
     * @param nameCanEmpty 蓝牙设备名称是否可以为空 默认false-不可为空
     * @param scanBleOnly 是否仅搜索低功耗蓝牙设备 默认false-搜索全量蓝牙设备
     * @return scanResultCallback 搜索结果回调
     */
    @SuppressLint("StaticFieldLeak")
    fun scanBluetoothDevice(enable: Boolean, showAnim: Boolean = true, nameCanEmpty: Boolean = false, scanBleOnly: Boolean = false, scanResultCallback: (BluetoothDevice) -> Unit): Boolean {
        Log.i(Tag, "开始扫描BLE设备: $enable $nameCanEmpty")

        val checkPermission = checkPermission()
        if (!checkPermission) {
            return false
        }

        if (enable) {
            if (showAnim) {
                progressDialog?.show()
            }
            if (scanBleOnly) {
                ScanBleDeviceManager.startBleScanDevice(bluetoothAdapter, nameCanEmpty, scanResultCallback)
            } else {
                mContext?.let { ScanAllDeviceManager.startAllScanDevice(it, bluetoothAdapter, nameCanEmpty, scanResultCallback) }
            }
        } else {
            if (showAnim) {
                progressDialog?.dismiss()
            }
            if (scanBleOnly) {
                ScanBleDeviceManager.stopBleScanDevice()
            } else {
                ScanAllDeviceManager.stopAllScanDevice()
            }
        }

        scanBluetoothDeviceState = enable
        return true
    }

    /**
     * 查询全部搜索到的蓝牙设备
     */
    fun queryAllScanBluetoothDevices(): List<BluetoothDevice> {
        return if (isClassicType) {
            ScanAllDeviceManager.queryAllScanBluetoothDevices()
        } else {
            ScanBleDeviceManager.queryAllScanBluetoothDevices()
        }
    }

    /**
     * 连接到蓝牙设备
     */
    fun connectToBluetoothDevice(device: BluetoothDevice, resultCallback: (Boolean) -> Unit) {
        if (scanBluetoothDeviceState) {
            resultCallback(false)
            Toast.makeText(mContext, mContext?.resources?.getString(R.string.str_scanning_no_connect), Toast.LENGTH_SHORT).show()
        } else {
            YDSRepeatClickRefuseHelper.clickButton(object : YDSRepeatClickRefuseHelper.OnClickListener {
                override fun onClickEnabled() {
                    if (isClassicType) {
                        ConnectClassicDeviceManager.connectToDevice(device, resultCallback)
                    } else {
                        ConnectBleDeviceManager.connectToDevice(mContext!!, device, resultCallback)
                    }
                }
            })
        }
    }

    // 定义广播接收器
    private val bluetoothReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val action = intent.action
            if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
                // 获取连接的设备
                YDSRepeatClickRefuseHelper.clickButton(1, 500, object : YDSRepeatClickRefuseHelper.OnClickListener {
                    override fun onClickEnabled() {
                        val device: BluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)!!
                        Log.d(Tag, "Device connected: ${device.name}, Address: ${device.address}  $mOnConnectStateChangedListener")
                        mOnConnectStateChangedListener?.onConnectStateChangedCallback(true)
                    }
                })
            } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED == action) {
                // 获取断开连接的设备
                YDSRepeatClickRefuseHelper.clickButton(2, 500, object : YDSRepeatClickRefuseHelper.OnClickListener {
                    override fun onClickEnabled() {
                        val device: BluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)!!
                        Log.d(Tag, "Device disconnected: ${device.name}, Address: ${device.address}  $mOnConnectStateChangedListener")
                        TempData.clear()
                        mOnConnectStateChangedListener?.onConnectStateChangedCallback(false)
                    }
                })
            }
        }
    }

    /**
     * 注册蓝牙连接状态广播接收器
     */
    private fun onRegisterBluetoothDeviceConnectStateObserver() {
        onUnRegisterBluetoothDeviceConnectStateObserver()
        YDSDelayHelper.delay(200) {
            val filter = IntentFilter()
            filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
            filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
            mContext?.registerReceiver(bluetoothReceiver, filter)
        }
    }

    /**
     * 取消注册蓝牙连接状态广播接收器
     */
    private fun onUnRegisterBluetoothDeviceConnectStateObserver() {
        try {
            mContext?.unregisterReceiver(bluetoothReceiver)
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    /**
     * 发送数据到蓝牙设备
     */
    fun sendDataToBluetoothDevice(data: ByteArray, sendResultCallback: (Boolean) -> Unit, receiveResultCallback: (ByteArray) -> Unit) {
        if (isClassicType) {
            ConnectClassicDeviceManager.sendDataToBleDevice(data, sendResultCallback, receiveResultCallback)
        } else {
            ConnectBleDeviceManager.sendDataToBleDevice(data, sendResultCallback, receiveResultCallback)
        }
    }

    /**
     * 断开与蓝牙设备的连接
     */
    fun disconnectFromBluetoothDevice() {
        if (isClassicType) {
            ConnectClassicDeviceManager.disconnectFromDevice()
        } else {
            ConnectBleDeviceManager.disconnectFromDevice()
        }
    }

}